package com.kun.framework.core.controller;

import com.kun.framework.core.factory.StageSingletonFactory;
import com.kun.framework.core.util.ComUtil;
import javafx.scene.Scene;
import javafx.scene.layout.Region;
import javafx.stage.Stage;
import javafx.stage.Window;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 抽象视图类
 *
 * @author gzc
 * @since 2024/9/22
 */
public abstract class AbstractController {
    protected Logger log;
    protected Stage stage;
    protected Scene scene;
    protected boolean isValidCloseCallBack = true;
    protected Region node;

    protected boolean isRunBeforeCallback = false;

    public void initializeScene(Region parent) {
        initialize(parent, false);
    }

    public void initialize(Region parent) {
        initialize(parent, true);
    }

    public void initialize(Region parent, boolean isStage) {
        this.node = parent;
        ComUtil.jfxThreadRun(() -> {
            // 初始化数据
            if (parent != null && parent.getScene() == null) {
                scene = new Scene(parent);
            }
            if (isStage) {
                Window window = scene.getWindow();
                if (window == null) {
                    stage = new Stage();
                    stage.setScene(scene);
                } else {
                    stage = (Stage) window;
                }
            }
            log = LoggerFactory.getLogger(this.getClass());
            StageSingletonFactory.addInstance(this);
        });
    }

    /**
     * 响应式赋值子节点宽度
     *
     * @param mainBoxWidth 主容器宽度
     */
    protected abstract void reactiveWidth(double mainBoxWidth);

    /**
     * 响应式赋值子节点高度
     *
     * @param mainBoxHeight 主容器高度
     */
    protected abstract void reactiveHeight(double mainBoxHeight);

    /**
     * 初始化布局之前执行
     */
    protected void initLayoutBefore() {
    }

    /**
     * 初始化布局
     */
    protected void initLayout() {
    }

    /**
     * 注册监听器
     */
    protected void registerMonitor() {
    }

    /**
     * 程序启动后的回调函数
     */
    public void runBeforeCallback() {
        ComUtil.jfxThreadRun(() -> {
            if (isRunBeforeCallback) {
                return;
            }
            // 执行生命周期函数
            initLayoutBefore();
            initLayout();
            reactive();
            registerMonitor();
            initDataBeforeCallback();
            initData();
            initDataAfterCallback();
            isRunBeforeCallback = true;
        });
    }

    /**
     * 响应式
     */
    protected void reactive() {
        reactiveWidth(node.getPrefWidth());
        reactiveHeight(node.getPrefHeight());
        this.stage.heightProperty().addListener((observable, oldValue, newValue) -> {
            reactiveHeight(newValue.doubleValue());
        });
        this.stage.widthProperty().addListener((observable, oldValue, newValue) -> {
            reactiveWidth(newValue.doubleValue());
        });
    }

    /**
     * 初始化数据
     */
    protected void initData() {
    }

    /**
     * 初始化前调用
     */
    protected void initDataBeforeCallback() {
    }

    /**
     * 初始化后调用
     */
    protected void initDataAfterCallback() {
    }

    /**
     * 页面关闭时的回调函数
     */
    public void stopCallback() {
    }

    /**
     * 获取舞台
     *
     * @return 舞台对象
     */
    public Scene getScene() {
        return scene;
    }

    /**
     * 展示窗口
     */
    public void show() {
        ComUtil.jfxThreadRun(() -> {
            if (!stage.isShowing()) {
                stage.show();
            }
            // 注册窗口关闭监听事件
            stage.setOnCloseRequest(event -> {
                // 执行窗口关闭函数
                stopCallback();
                // 设置窗口关闭回调状态为无效
                isValidCloseCallBack = false;
                stage.close();
                StageSingletonFactory.removeInstance(this.getClass());
            });
        });
    }

    /**
     * 展示窗口并保持实例存活（关闭窗口不会清除实例）
     */
    public void showAndStayAlive() {
        ComUtil.jfxThreadRun(() -> {
            if (!stage.isShowing()) {
                stage.show();
            }
            // 注册窗口关闭监听事件
            stage.setOnCloseRequest(event -> {
                // 执行窗口关闭函数
                stopCallback();
                stage.hide();
            });
        });
    }

    public void showAndAwait() {
        ComUtil.jfxThreadRun(() -> {
            if (!stage.isShowing()) {
                stage.showAndWait();
            }
            // 注册窗口关闭监听事件
            stage.setOnCloseRequest(event -> {
                // 执行窗口关闭函数
                stopCallback();
                // 设置窗口关闭回调状态为无效
                isValidCloseCallBack = false;
                stage.close();
                StageSingletonFactory.removeInstance(this.getClass());
            });
        });
    }

    public Stage getStage() {
        return stage;
    }

    /**
     * 关闭窗口
     */
    public void close() {
        stage.close();
    }
}
